package com.zzw.service.Impl;

import com.zzw.config.RedisPersistenceConfig;
import com.zzw.service.RedisPersistenceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

/**
 * Redis持久化服务实现类
 * 提供监控和控制Redis持久化的方法
 */
@Service
public class RedisPersistenceServiceImpl implements RedisPersistenceService {

    private static final Logger logger = LoggerFactory.getLogger(RedisPersistenceServiceImpl.class);
    
    @Autowired
    private RedisPersistenceConfig redisPersistenceConfig;
    
    @Value("${redis.host}")
    private String redisHost;
    
    @Value("${redis.port}")
    private int redisPort;
    
    @Value("${redis.password:}")
    private String redisPassword;
    
    @Value("${redis.config.path:./redis-config}")
    private String configPath;
    
    /**
     * 获取Redis持久化状态
     */
    @Override
    public Map<String, Object> getPersistenceStatus() {
        Map<String, Object> status = new HashMap<>();
        
        try (Jedis jedis = getJedisClient()) {
            // 获取RDB状态
            Map<String, Object> rdbInfo = getRdbStatus(jedis);
            status.put("rdb", rdbInfo);
            
            // 获取AOF状态
            Map<String, Object> aofInfo = getAofStatus(jedis);
            status.put("aof", aofInfo);
            
            // 获取配置文件信息
            status.put("configFile", getConfigFileInfo());
            
        } catch (Exception e) {
            logger.error("获取Redis持久化状态失败", e);
            status.put("error", e.getMessage());
        }
        
        return status;
    }
    
    /**
     * 触发RDB持久化
     */
    @Override
    public boolean triggerRdbSave() {
        try (Jedis jedis = getJedisClient()) {
            String result = jedis.bgsave();
            logger.info("触发RDB持久化结果: " + result);
            return "Background saving started".equals(result);
        } catch (Exception e) {
            logger.error("触发RDB持久化失败", e);
            return false;
        }
    }
    
    /**
     * 触发AOF重写
     */
    @Override
    public boolean triggerAofRewrite() {
        try (Jedis jedis = getJedisClient()) {
            String result = jedis.bgrewriteaof();
            logger.info("触发AOF重写结果: " + result);
            return "Background append only file rewriting started".equals(result);
        } catch (Exception e) {
            logger.error("触发AOF重写失败", e);
            return false;
        }
    }
    
    /**
     * 更新持久化配置
     */
    @Override
    public boolean updatePersistenceConfig(boolean enableRdb, boolean enableAof) {
        try {
            // 更新配置类中的设置并重新生成配置文件
            redisPersistenceConfig.updatePersistenceConfig(enableRdb, enableAof);
            
            // 通知Redis重新加载配置（需要Redis支持CONFIG REWRITE命令）
            try (Jedis jedis = getJedisClient()) {
                // 动态设置RDB
                if (enableRdb) {
                    jedis.configSet("save", "900 1 300 10 60 10000");
                } else {
                    jedis.configSet("save", "");
                }
                
                // 动态设置AOF
                jedis.configSet("appendonly", enableAof ? "yes" : "no");
                
                // 请求Redis保存配置（如果支持）
                try {
                    jedis.configRewrite();
                    logger.info("Redis配置已重写保存");
                } catch (Exception e) {
                    logger.warn("Redis不支持CONFIG REWRITE命令，配置将在Redis重启后生效", e);
                }
            }
            
            return true;
        } catch (Exception e) {
            logger.error("更新Redis持久化配置失败", e);
            return false;
        }
    }
    
    /**
     * 获取RDB配置和状态信息
     */
    private Map<String, Object> getRdbStatus(Jedis jedis) {
        Map<String, Object> rdbInfo = new HashMap<>();
        
        try {
            // 获取Redis信息
            String info = jedis.info("Persistence");
            
            // 解析RDB相关信息
            String[] lines = info.split("\n");
            for (String line : lines) {
                if (line.contains("rdb_")) {
                    String[] parts = line.split(":");
                    if (parts.length == 2) {
                        rdbInfo.put(parts[0].trim(), parts[1].trim());
                    }
                }
            }
            
            // 获取RDB配置
            String saveConfig = jedis.configGet("save").get(1);
            rdbInfo.put("save_config", saveConfig);
            
            // RDB文件路径
            String dbFilename = jedis.configGet("dbfilename").get(1);
            String dir = jedis.configGet("dir").get(1);
            rdbInfo.put("rdb_file_path", dir + "/" + dbFilename);
            
            // 检查RDB文件是否存在及大小
            File rdbFile = new File(dir + "/" + dbFilename);
            if (rdbFile.exists()) {
                rdbInfo.put("rdb_file_exists", true);
                rdbInfo.put("rdb_file_size_bytes", rdbFile.length());
                rdbInfo.put("rdb_file_last_modified", rdbFile.lastModified());
            } else {
                rdbInfo.put("rdb_file_exists", false);
            }
            
        } catch (Exception e) {
            logger.error("获取RDB状态信息失败", e);
            rdbInfo.put("error", e.getMessage());
        }
        
        return rdbInfo;
    }
    
    /**
     * 获取AOF配置和状态信息
     */
    private Map<String, Object> getAofStatus(Jedis jedis) {
        Map<String, Object> aofInfo = new HashMap<>();
        
        try {
            // 获取Redis信息
            String info = jedis.info("Persistence");
            
            // 解析AOF相关信息
            String[] lines = info.split("\n");
            for (String line : lines) {
                if (line.contains("aof_")) {
                    String[] parts = line.split(":");
                    if (parts.length == 2) {
                        aofInfo.put(parts[0].trim(), parts[1].trim());
                    }
                }
            }
            
            // 获取AOF配置
            aofInfo.put("appendonly", jedis.configGet("appendonly").get(1));
            aofInfo.put("appendfsync", jedis.configGet("appendfsync").get(1));
            aofInfo.put("auto-aof-rewrite-percentage", jedis.configGet("auto-aof-rewrite-percentage").get(1));
            aofInfo.put("auto-aof-rewrite-min-size", jedis.configGet("auto-aof-rewrite-min-size").get(1));
            
            // AOF文件路径
            String aofFilename = jedis.configGet("appendfilename").get(1);
            String dir = jedis.configGet("dir").get(1);
            aofInfo.put("aof_file_path", dir + "/" + aofFilename);
            
            // 检查AOF文件是否存在及大小
            File aofFile = new File(dir + "/" + aofFilename);
            if (aofFile.exists()) {
                aofInfo.put("aof_file_exists", true);
                aofInfo.put("aof_file_size_bytes", aofFile.length());
                aofInfo.put("aof_file_last_modified", aofFile.lastModified());
            } else {
                aofInfo.put("aof_file_exists", false);
            }
            
        } catch (Exception e) {
            logger.error("获取AOF状态信息失败", e);
            aofInfo.put("error", e.getMessage());
        }
        
        return aofInfo;
    }
    
    /**
     * 获取配置文件信息
     */
    private Map<String, Object> getConfigFileInfo() {
        Map<String, Object> configInfo = new HashMap<>();
        
        try {
            File configFile = new File(configPath + "/redis.conf");
            if (configFile.exists()) {
                configInfo.put("exists", true);
                configInfo.put("path", configFile.getAbsolutePath());
                configInfo.put("size_bytes", configFile.length());
                configInfo.put("last_modified", configFile.lastModified());
                
                // 读取配置文件内容
                StringBuilder content = new StringBuilder();
                try (BufferedReader reader = new BufferedReader(new FileReader(configFile))) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        content.append(line).append("\n");
                    }
                }
                configInfo.put("content", content.toString());
                
            } else {
                configInfo.put("exists", false);
            }
        } catch (Exception e) {
            logger.error("获取配置文件信息失败", e);
            configInfo.put("error", e.getMessage());
        }
        
        return configInfo;
    }
    
    /**
     * 获取Jedis客户端
     */
    private Jedis getJedisClient() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        JedisPool jedisPool;
        
        if (redisPassword != null && !redisPassword.trim().isEmpty()) {
            jedisPool = new JedisPool(poolConfig, redisHost, redisPort, 2000, redisPassword);
        } else {
            jedisPool = new JedisPool(poolConfig, redisHost, redisPort);
        }
        
        return jedisPool.getResource();
    }
} 